var express = require('express');
var router = express.Router();
var moment = require('moment');
var fs = require('fs');
const { spawnSync, spawn } = require('child_process');

moment.locale('zh-cn');

function getRandomNum(Min, Max) {
    var Range = Max - Min;
    var Rand = Math.random();
    return (Min + Math.round(Rand * Range));
}

var pad = function(tbl) {
    return function(num, n){
        n = n - (''+num).length;
        // console.log('asdasd=='+n);
        return (0 >= n) ? num : (tbl[n] || (tbl[n] = Array(n + 1).join(0)))+num;
    }    
}([]);

function Utf8ArrayToStr(array) {
    var out, i, len, c;
    var char2, char3;

    out = "";
    len = array.length;
    i = 0;
    while (i < len) {
        c = array[i++];
        switch (c >> 4) {
            case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
                // 0xxxxxxx
                out += String.fromCharCode(c);
                break;
            case 12: case 13:
                // 110x xxxx 10xx xxxx
                char2 = array[i++];
                out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
                break;
            case 14:
                // 1110 xxxx 10xx xxxx 10xx xxxx
                char2 = array[i++];
                char3 = array[i++];
                out += String.fromCharCode(((c & 0x0F) << 12) |
                    ((char2 & 0x3F) << 6) |
                    ((char3 & 0x3F) << 0));
                break;
        }
    }

    return out;
}

router.process_async = function(req, callback, callback_err) {
    var pkgname = req.body.pkgname;
    var version = req.body.version;
    var pyver = req.body.pyver;
    var abiver = req.body.abiver;
    var osver = req.body.osver;
    var repo = req.body.repo;
    var pip = req.body.pip;

    if (pkgname && pkgname.length > 0) {
        // res.send('文件上传成功');
        // console.log(req.file);
        if (version.length > 0) {
            pkgname = pkgname + '==' + version;
        }
        // 命令解释如下：
        //   pip download open3d==0.16.0 -i https://pypi.tuna.tsinghua.edu.cn/simple/  
        //   --platform manylinux2014_aarch64 #操作系统版本，这里的版本测试了一下只能是包上写的啥就是啥，
        //          #命名方式有很多，可以先获取列表，在进行拆分分解
        //   --python-version 3.8  #3.8 38 都代表同样的版本
        //   --only-binary=:all: #模块文件类型过滤器
        //   --implementation cp #解释器类型 ‘pp’, ‘jy’, ‘cp’, ‘ip’
        var extParams = '';
        if (pyver.length > 2 || osver.length > 0) {
            extParams = '--only-binary=:all:';
            if (pyver.indexOf('.') > 0) {
                pyver = pyver.substring(0, pyver.indexOf('.'));
            }
            if (pyver.length > 2) {
                var py = pyver.substring(0, 2);
                var ver = pyver.substring(2);
                if (ver == '2' || ver == '3') {
                    ver += '7';
                }
                extParams += ' --implementation ' + py + ' --python-version ' + ver;
            }
            if (osver.length > 0) {
                extParams += ' --platform ' + osver;
            }
            if (abiver.length > 0 && abiver[abiver.length - 1] == 'm') {
                extParams += ' --abi ' + abiver;
            }
        }
        console.log('收到一个请求：' + repo + ' ' + pkgname + ' ' + extParams);

        var formatDate = moment().format('YYYYMMDDHHmmss'); /*格式化时间*/
        var randNum = getRandomNum(0, 999999);
        var fileKey = formatDate + '_' + pad(randNum, 6);
        // console.log('[DEBUG]==fileKey: ' + fileKey);
        var env = process.env;
        env['PIP'] = pip;

        var child = spawn('./bin/pip_build', [
            '0', repo, pkgname, fileKey, extParams
        ], {
            env: env
        });

        child.stdout.on('data', callback);
        child.stderr.on('data', callback_err);
    } else {
        res.send('文件提取失败');
    }
};

router.get('/env/pip', function (req, res, next) {
    // console.log(process.env.PATH);
    var pipArr = [];
    var pipMap = {};
    process.env.PATH.split(':').forEach(onePath => {
        if (fs.existsSync(onePath)) {
            var files = fs.readdirSync(onePath, { withFileTypes: true });
            files.forEach(oneFile => {
                if (!oneFile.isDirectory() && oneFile.name.match(/^pip[0-9\.-_]*$/)) {
                    const fullPath = onePath + '/' + oneFile.name;
                    var versionStr = Utf8ArrayToStr(spawnSync(fullPath, ['-V']).stdout);
                    if (versionStr.endsWith('\n')) {
                        versionStr = versionStr.substring(0, versionStr.length - 1);
                    }
                    if (versionStr.match(/^(pip .*) from .* (\(python .*\))$/)) {
                        versionStr = versionStr.replace(/^(pip .*) from .* (\(python .*\))$/, '$1 $2');
                        if (!pipMap[versionStr]) {
                            pipArr.push({
                                fullPath: fullPath,
                                name: oneFile.name,
                                versionStr: versionStr,
                            });
                            pipMap[versionStr] = 1;
                        }
                    }
                }
            });
        }
    });
    res.send(JSON.stringify(pipArr));
});

module.exports = router;
